
//
// 110222 - AH - Created.
// 110227 - AH - getIndex().
// 110301 - AH - teared(boolean) and getPopupMenu().
// 120321 - AH - Removed @Override for interface method (1.5 compatible).
//

package org.soekrat.gui.swing.studio;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;

import org.soekrat.engine.Soekrat2Engine;

/**
 * <p>
 *   Base class for studio views.
 * </p>
 * @author Arne Halvorsen (AHA)
 * @author Laetitia Le Chatton (LLC) 
 */
@SuppressWarnings("serial")
public abstract class RatStudioView extends JPanel 
  implements Comparable<RatStudioView>
{
  private RatStudioViewPane m_context=null;
  
  private int m_idx;
  
  private final String m_title;
  
  private final JPopupMenu m_pm;
  
  private final JPanel m_contentPanel=new JPanel(); 
  
  private final Action m_tearOffAction=
    new AbstractAction("Open in a New Window")
  {
    public void actionPerformed(ActionEvent e)
    {
      m_context.tearOff(RatStudioView.this);
      teared(true);
    }
  };
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * @param title {@link #getTitle()}.
   */
  protected RatStudioView(String title, Soekrat2Engine engine)
  {
    if (title==null)
    {
      throw new NullPointerException("title");
    }
    
    title=title.trim();
    if (title.length()==0)
    {
      throw new IllegalArgumentException("title the empty string");
    }
    
    m_title=title;
    
    m_pm=createPopupMenu();
    new PopupListener(m_pm, this);
    
    setLayout(new BorderLayout());
    add(m_contentPanel, BorderLayout.CENTER);
    
    //JPanel north=new JPanel(new FlowLayout(FlowLayout.RIGHT));
    JPanel north=new JPanel(new BorderLayout());
    north.add(new ConversationTitleEditor(engine, 
      isConversationTitleEditable()), BorderLayout.WEST);
    north.add(new JButton(m_tearOffAction), BorderLayout.EAST);
    add(north, BorderLayout.NORTH);
  }
  
  protected boolean isConversationTitleEditable(){ return true; }
  
  /**
   * <p>
   *   Gets panel content is to be placed in.
   * </p>
   * @return Panel.
   */
  JPanel getContentPanel(){ return m_contentPanel; }
  
  // Invoked from RatStudioViewPane when this is added.
  void setContext(RatStudioViewPane rsvp, int idx)
  {
    if (rsvp==null)
    {
      throw new NullPointerException("rsvp");
    }
    if (idx<0)
    {
      throw new IllegalArgumentException("idx<0 : "+idx);
    }
    
    if (m_context!=null)
    {
      throw new IllegalArgumentException("is in context");
    }
    
    m_idx=idx;
    m_context=rsvp;
  }
  
  /**
   * <p>
   *   Gets 
   *   {@link RatStudioViewPane} this is in.
   * </p>
   * @return {@code RatStudioViewPane}.
   */
  RatStudioViewPane getContext()
  {
    if (m_context==null)
    {
      throw new IllegalStateException("no context");
    }
    
    return m_context;
  }
  
  /**
   * <p>
   *   Gets index of {@code this} in the
   *   {@link RatStudioViewPane} it belong to.
   * </p>
   * @return Index.
   */
  int getIndex()
  {
    if (m_context==null)
    {
      throw new IllegalStateException("no context");
    }
    
    return m_idx;
  }
  
  /**
   * <p>
   *   Gets component's title.
   * </p>
   * @return Title.
   */
  public String getTitle(){ return m_title; }
  
  /**
   * <p>
   *   Tells if {@code this} is teared of or not.
   * </p>
   * @param v {@code true} if is teared of and {@code false} if it is not.
   */
  void teared(boolean v){ m_tearOffAction.setEnabled(!v); }
  
  /**
   * <p>
   *   Gets popup menu associated with {@code this}.
   * </p>
   * @return Menu.
   */
  protected final JPopupMenu getPopupMenu(){ return m_pm; }
  
  private JPopupMenu createPopupMenu()
  {
    JPopupMenu retVal=new JPopupMenu();
    
    retVal.add(m_tearOffAction);
    
    return retVal;
  }

  // Specified in Comparable<RatStudioView>.
  public int compareTo(RatStudioView o) 
  {
    int idx=m_idx;
    int idxO=o.m_idx;
    return idx<idxO ? -1 : (idx==idxO ? 0 : 1);
  }
  
}
